package models

import (
	"errors"
	"fmt"
	"github.com/prometheus/common/log"
	err2 "remote_cmd/error"
)

const (
	ReadOnly = "readOnly"
	Edit     = "edit"
)

type DirChange struct {
	Ip  string `json:"ip"`
	Dir string `json:"dir"`
}

type File struct {
	Ip          string `json:"ip"`
	FileName    string `json:"fileName"`
	Type        string `json:"type"`
	ContentByte []byte `json:"contentByte"`
	ContentStr  string `json:"contentStr"`
}

type SyncFile struct {
	Master     string   `json:"master"`
	Nodes      []string `json:"nodes"`
	MasterFile string   `json:"masterFile"`
	NodeFile   string   `json:"nodeFile"`
	content    []byte
}

func (f *File) Edit() error {
	linux, ok := LinuxCache[f.Ip]
	if !ok {
		return errors.New(fmt.Sprintf("ip[%s] not logged in", f.Ip))
	}
	_, err := linux.Exec(fmt.Sprintf("echo '%s' > %s", f.ContentStr, f.FileName))
	return err
}

func (f *File) Cat() error {
	linux, ok := LinuxCache[f.Ip]
	if !ok {
		return errors.New(fmt.Sprintf("ip[%s] not logged in", f.Ip))
	}
	content, err := linux.Exec(fmt.Sprintf("cat %s", f.FileName))
	if err != nil {
		return err
	}
	f.ContentByte = content
	f.ParseContent()
	return nil
}

func (f *File) ParseContent() {
	if f.ContentByte == nil || len(f.ContentByte) == 0 {
		f.ContentStr = ""
		return
	}
	f.ContentStr = string(f.ContentByte)
}

func (syncFile *SyncFile) SyncFile() error {
	linux, ok := LinuxCache[syncFile.Master]
	if !ok {
		return err2.ErrorList{errors.New(fmt.Sprintf("master[%s] not logged in", syncFile.Master))}
	}
	content, err := linux.Exec(fmt.Sprintf("cat %s", syncFile.MasterFile))
	if err != nil {
		return err2.ErrorList{err}
	}
	syncFile.content = content
	var resErrs err2.ErrorList
	for _, nodeIp := range syncFile.Nodes {
		linuxNode, ok := LinuxCache[nodeIp]
		// 如果未登录，自动登录
		if !ok {
			linuxNode = &Linux{
				Ip:       nodeIp,
				Name:     LinuxName,
				Password: LinuxPassword,
			}
			err := linuxNode.Login()
			if err != nil {
				log.Errorf("node[%s] login fail: %s", nodeIp, err.Error())
				resErrs = append(resErrs, errors.New(fmt.Sprintf("node[%s] login error: %s", nodeIp, err.Error())))
				continue
			}
		}
		_, err = linuxNode.Exec(fmt.Sprintf("echo '%s' > %s", string(syncFile.content), syncFile.NodeFile))
		if err != nil {
			log.Errorf("node[%s] write file error: %s", nodeIp, err.Error())
			resErrs = append(resErrs, errors.New(fmt.Sprintf("node[%s] write file error: %s", nodeIp, err.Error())))
		}
	}
	return resErrs
}
